﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Timers;

namespace KrisThom.Execute
{

    public enum WindowStyle { Hidden, Maximized, Minimized, Normal } 

    public class Execute : IDisposable
    {
        private Process _process;
        private Timer _timer;


        /// <summary>
        /// Execute command and specifiy how long to run in milliseconds.
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="arguments"></param>
        /// <param name="workingDirectory"></param>
        /// <param name="ms"></param>
        /// <returns></returns>
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public Boolean RunWithTimer(String fileName, String arguments, String workingDirectory, WindowStyle window, double ms)
        {
            Boolean result = false;

            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = fileName;
                startInfo.Arguments = arguments;
                startInfo.WorkingDirectory = workingDirectory;
                startInfo.WindowStyle = GetWindowStyle(window);
                                
                _process = Process.Start(startInfo);

                KillTimer(ms);

                _process.WaitForExit();
                result = true;
            }
            catch
            {
                return false;
            }

            return result;
        }

        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public Boolean RunWait(String fileName, String arguments, WindowStyle window)
        {
            Boolean result = false;

            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = fileName;
                startInfo.Arguments = arguments;
                startInfo.WindowStyle = GetWindowStyle(window);

                _process = Process.Start(startInfo);
                _process.WaitForExit();

                result = true;
            }
            catch
            {
                return false;
            }

            return result;

        }

        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public Boolean Run(String fileName, String arguments, WindowStyle window)
        {
            Boolean result = false;

            try
            {
                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.FileName = fileName;
                startInfo.Arguments = arguments;
                startInfo.WindowStyle = GetWindowStyle(window);

                _process = Process.Start(startInfo);

                result = true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
                return false;
            }

            return result;

        }


        internal static ProcessWindowStyle GetWindowStyle(WindowStyle style)
        {
            
            switch (style)
            {
                case WindowStyle.Hidden:
                    return ProcessWindowStyle.Hidden;
                case WindowStyle.Maximized:
                    return ProcessWindowStyle.Maximized;
                case WindowStyle.Minimized:
                    return ProcessWindowStyle.Minimized;
                case WindowStyle.Normal:
                    return ProcessWindowStyle.Normal;
                default:
                    throw new System.ArgumentException("WindowStyle has unknown type","style");
            }


            //return pws;
        }


        /// <summary>
        /// Timer to kill the process
        /// </summary>
        /// <param name="seconds"></param>
        private void KillTimer(double ms)
        {
            _timer = new Timer(ms);
            _timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            _timer.Enabled = true;
        }

        // Kill the process.
        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            _timer.Enabled = false;

            try
            {
                _process.Kill();
            }
            catch (Exception ex)
            { 
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
        

        //dispose
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                _timer.Close();
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }


    }

}
